import os
import sys

from InstallDbInterface import InstallDbInterface
from Utils import Utils

class InstallDbForKylin(InstallDbInterface):
    def __init__(self, config, xml_tree, env):
        self.config = config
        self.env = env
        self.xml_tree = xml_tree
        self.export_path = 'export LD_LIBRARY_PATH=/opt/software/issedb/script/ISpylib/clib:$LD_LIBRARY_PATH'
        self.dependent_lib = ['readline',
                                'python2',
                                'libicu',
                                'cracklib',
                                'libxslt',
                                'tcl',
                                'perl',
                                'openldap',
                                'pam',
                                'systemd-libs',
                                'bzip2',
                                'gettext',
                                'libaio',
                                'ncurses-libs',
                                'libatomic']
        self.params = {'fs.aio-max-nr': '1048576',
                       'fs.file-max': '76724600',
                       'kernel.sem': '4096 2097152000 4096 512000',
                       'kernel.shmall': '26843545',
                       'kernel.shmmax': '68719476736',
                       'kernel.shmmni': '819200',
                       'net.ipv4.tcp_retries1': '5',
                       'net.ipv4.tcp_syn_retries': '5',
                       'net.core.netdev_max_backlog': '10000',
                       'net.core.rmem_default': '262144',
                       'net.core.rmem_max': '4194304',
                       'net.core.wmem_default': '262144',
                       'net.core.wmem_max': '4194304',
                       'net.core.somaxconn': '4096',
                       'net.ipv4.tcp_fin_timeout': '60',
                       'vm.dirty_background_bytes': '409600000',
                       'vm.dirty_expire_centisecs': '3000',
                       'vm.dirty_ratio': '80',
                       'vm.dirty_writeback_centisecs': '50',
                       'vm.overcommit_memory': '0',
                       'vm.swappiness': '60',
                       'net.ipv4.ip_local_port_range': '40000 65535',
                       'fs.nr_open': '20480000'}
        self.limits_conf = {'issedb soft nproc unlimited',
                            'issedb hard nproc unlimited',
                            'issedb soft stack unlimited',
                            'issedb hard stack unlimited',
                            'issedb soft core unlimited',
                            'issedb hard core unlimited',
                            'issedb soft memlock unlimited',
                            'issedb hard memlock unlimited',
                            'issedb soft nofile 10240000',
                            'issedb hard nofile 10240000'
                            }

    def ipc_setting(self, config_path, active_cmd):
        ret, msg = Utils.check_ipc_parameters(config_path)
        if ret is not True:
            print("- check ipc parameters, err msg {}.".format(msg))
            return False, msg
        if msg == 'found':
            print("- check ipc parameters in {}, RemoveIPC=no.".format(config_path))
        else:
            ret, msg = Utils.set_ipc_parameters(config_path)
            if ret is not True:
                print("- set ipc parameters failed, err msg {}.".format(msg))
                return False, msg
            ret, msg = Utils.active_ipc_parameters(active_cmd)
            if ret is not True:
                print("- active ipc parameters, err msg {}.".format(msg))
                return False, msg
            print("- successfully set \"RemoveIPC=no\" in the file, {}".format(config_path))
        return True, 'success'

    def lib_need_install(self, lib, installed_lib_list):
        for lib_name in installed_lib_list:
            if lib in lib_name:
                return False
        return True

    def create_group_and_user(self):
        group_name = self.config['userGroup'].strip()
        user_name = self.config['user'].strip()
        if Utils.query_user_group(group_name) is not True:
            group_ret, msg = Utils.create_user_group(group_name)
            if group_ret is not True:
                return False, 'create user-group {} failed, err msg {}'.format(group_name, msg)
        if Utils.query_user(user_name) is not True:
            user_ret, msg = Utils.create_user(group_name, user_name)
            if user_ret is not True:
                return False, 'create user {} failed, err msg {}'.format(user_name, msg)
            pw_ret, msg = Utils.set_user_passwd(user_name, self.config['userPasswd'])
            if pw_ret is not True:
                return False, 'set user {} password failed, err msg {}'.format(user_name, msg)
        return True, 'create user-group {} and user {} success.'.format(group_name, user_name)

    def preinstall(self):
        # -----------create user-group and user beginning----------------------------
        group_name = self.config['userGroup'].strip()
        user_name = self.config['user'].strip()
        ret, msg = self.create_group_and_user()
        if ret is not True:
            print("- add user-group {} and user {} failed, err msg {}.".format(group_name, user_name, msg))
            return False, msg
        print("- add user-group {} and user {} success.".format(group_name, user_name))
        # -----------close firewalled-------------------------------
        ret, msg = Utils.check_firewalled_status()
        if ret is not True:
            print("- check firewalled status failed, err msg {}.".format(msg))
            return False, msg
        if msg == 'running':
            ret, msg = Utils.close_firewalled()
            if ret is not True:
                print("- close firewalled failed, err msg {}.".format(msg))
                return False, msg
            ret, msg = Utils.check_firewalled_status()
            if ret is True and msg == 'not running':
                print("- close firewalled success.")
        else:
            print("- firewalled is not running.")
        # -----------close selinux-------------------------------
        ret, msg = Utils.get_selinux_satus()
        if ret is not True:
            print("- get selinux status failed, err msg {}.".format(msg))
            return False, msg
        if msg.lower().find('disabled') >= 0:
            print('- selinux disabled.')
        else:
            ret, msg = Utils.temporary_close_selinux()
            if ret is not True:
                print("- temporary close selinux failed, msg {}.".format(msg))
                return False, msg
            print("- temporary close selinux success.")
        # -----------install lib-------------------------------
        ret, lib_list, msg = Utils.get_installed_lib()
        if ret is not True:
            print("- get installed lib failed, err msg {}".format(msg))
            return False, msg
        need_install_lib = []
        for lib_name in self.dependent_lib:
            if self.lib_need_install(lib_name, lib_list):
                need_install_lib.append(lib_name)
        if len(need_install_lib) > 0:
            ret, msg = Utils.install_lib(need_install_lib)
            if ret is not True:
                print("- install lib failed, err msg {}.".format(msg))
                return False, msg
            print("- install lib success, lib as list {}.".format(need_install_lib))
        else:
            print("- all lib have been installed.")
        # -----------adjust system params-------------------------------
        ret, msg = Utils.adjust_system_parameters(self.params)
        if ret is not True:
            print("- adjust system parameters failed, err msg {}.".format(msg))
            return False, msg
        print("- adjust system parameters success.")
        # -----------ipc setting-------------------------------
        ret, msg = self.ipc_setting('/etc/systemd/logind.conf', 'daemon-reload')
        if ret is not True:
            return False, msg
        ret, msg = self.ipc_setting('/usr/lib/systemd/system/systemd-logind.service', 'restart systemd-logind')
        if ret is not True:
            return False, msg
        ret, msg = Utils.set_hostname(self.config['currentNode'].strip(), self.config['nodes'])
        if ret is not True:
            print("- set hostname failed, err msg {}.".format(msg))
            return False, msg
        ret, msg = Utils.mkdir_chomd(self.config['user'], self.config['userGroup'], self.config['installPath'])
        if ret is not True:
            print("- mkdir chomd failed, err msg {}.".format(msg))
            return False, msg
        ret, msg = Utils.mkdir_chomd(self.config['user'], self.config['userGroup'], self.config['dbPath'])
        if ret is not True:
            print("- mkdir chomd failed, err msg {}.".format(msg))
            return False, msg
        ret, msg = Utils.append_limits_conf(self.limits_conf)
        if ret is not True:
            print("- append limits.conf failed, err msg {}.".format(msg))
            return False, msg
        return True, 'success'

    def precheck(self):

        ret, msg = Utils.check_file_exist(self.config['packageName'].strip(), self.config['installPath'])
        if ret is not True:
            ret, msg = Utils.check_file_exist(self.config['packageName'].strip(), '.')
            if ret is not True:
                print("- package not found, err msg {}.".format(msg))
                return False, msg
            ret, msg = Utils.mv_file(self.config['packageName'].strip(), self.config['installPath'])
            if ret is not True:
                print("- mv package failed, err msg {}.".format(msg))
                return False, msg
        ret, msg = Utils.create_xml_config(self.xml_tree, self.config, self.config['installPath'])
        if ret is not True:
            print("- cluster_config.xml create failed, err msg {}.".format(msg))
            return False, msg
        ret, msg = Utils.unzip_package(self.config['packageName'].strip(), self.config['packageOmName'].strip(),
                                       self.config['installPath'])
        if ret is not True:
            print("- unzip package failed, err msg {}.".format(msg))
            return False, msg
        code, stdout, stderr = Utils.exec_command_in_shell("export LANG=en_US.UTF-8")
        if code != 0:
            print("- export LANG failed, err msg {}.".format(stderr))
            return False, stderr
        code, stdout, stderr = Utils.exec_command_in_shell("source /etc/profile")
        if code != 0:
            print("- source /etc/profile failed, err msg {}.".format(stderr))
            return False, stderr
        code, stdout, stderr = Utils.exec_command_in_shell(self.export_path)
        if code != 0:
            print("- export path failed, err msg {}.".format(stderr))
            return False, stderr
            # 赋权必须放在预检查之后，否则会被覆盖
        ret, msg = Utils.exec_chomd(self.config['user'], self.config['userGroup'], os.path.dirname(self.config['installPath']))
        if ret is not True:
            print("- exec chomd failed, err msg {}.".format(msg))
            return False, msg
        ret, msg = Utils.exec_chomd(self.config['user'], self.config['userGroup'], self.config['dbPath'])
        if ret is not True:
            print("- exec chomd failed, err msg {}.".format(msg))
            return False, msg
        # exec gs_preinstall
        ret, msg = Utils.exec_gs_preinstall(self.config['installPath'], self.config['currentNode'])
        if ret is not True:
            print("- exec gs_preinstall failed, err msg {}.".format(msg))
            return False, msg
        # 赋权必须放在预检查之后，否则会被覆盖
        ret, msg = Utils.exec_chomd(self.config['user'], self.config['userGroup'], os.path.dirname(self.config['installPath']))
        if ret is not True:
            print("- exec chomd failed, err msg {}.".format(msg))
            return False, msg
        ret, msg = Utils.exec_chomd(self.config['user'], self.config['userGroup'], self.config['dbPath'])
        if ret is not True:
            print("- exec chomd failed, err msg {}.".format(msg))
            return False, msg

        return True, 'success'

    def install(self):
        ret, msg = Utils.exec_install_database(self.config)
        if ret is not True:
            print("- exec install database failed, err msg {}.".format(msg))
            return False, msg
        return True, 'success'

    def after_install(self):
        pass

